package com.jule.teenpatti.game.service;

import com.jule.core.jedis.StoredObjManager;
import com.jule.teenpatti.base.dao.bean.RobotPool;
import com.jule.teenpatti.base.enums.RedisConst;
import com.jule.teenpatti.base.enums.RoleType;
import com.jule.teenpatti.game.model.PlayerInfo;
import com.jule.teenpatti.game.model.eenum.PlayTypeEnum;
import com.jule.teenpatti.game.play.AbstractTable;
import com.jule.teenpatti.game.utils.NumberUtils;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;

/**
 * 机器人输赢策略
 *
 * @author ran.wang
 *
 * @since 2018/11/1 10:24
 */
@Slf4j
public class RobotStrategyService {

    public static final RobotStrategyService OBJ = new RobotStrategyService();

    //机器人输赢
    private static final boolean common = false;
    private static final boolean win = true;


    /**
     * 当前机器人策略
     *
     * @return
     *          0-机器人正常操作<br/>
     *
     *          1-机器人执行赢的操作<br/>
     *
     */
    public boolean curRobotStrategy(int gameId){

        RobotPool pool = StoredObjManager.hget(RedisConst.ROBOT_POOL_CONFIG.getProfix()+gameId, RedisConst.ROBOT_POOL_CONFIG.getField(), RobotPool.class);
        if (pool == null){
            log.error("机器人资金池为空,game={}",gameId);
            return common;
        }

        //Y资金池变化金额=资金池的当前量-原始资金池量
        double poolChange = poolChange(pool);

        //Z总杀量池==每局杀量池(M)相加的总量
        double totalKillPool = totalKillPool(pool);

        log.debug("AI机器人换牌策略比值, x = {},z = {}" ,String.valueOf(poolChange), String.valueOf(totalKillPool));


        if (poolChange > totalKillPool * 1.1d){
            return common;
        }

        if (poolChange < totalKillPool * 0.9d){
            return win;
        }

        if (poolChange < totalKillPool * 1.1d
         && poolChange > totalKillPool * 0.9d){
            return common;
        }

        return common;
    }



    /**
     * 机器人赢的换牌策略
     * @param table
     * @return
     */
    public void robotChangeCard(AbstractTable table){
        PlayerInfo winner = null;

        String robotId = "";
        int[] robotCard = null;
        int[] robotFullCard = null;

        for (Integer seat : table.getInGamePlayers().keySet()){
            PlayerInfo player = table.getInGamePlayers().get(seat);
            if (player == null){
                continue;
            }

            //获取赢家
            if (table.getPlayType() == PlayTypeEnum.changecard.getGameId()){
                int[] maxcard = getMaxCard(player.getPlayerId(), table);
                player.setHandCards(maxcard);
            }

            //选中一个机器人备用
            if (player.getRoleType() == RoleType.ROBOT){
                robotId = player.getPlayerId();
                robotCard = player.getHandCards();
                robotFullCard = table.getPlayerCardsMap().get(robotId);
            }

            //初始化赢家
            if (winner == null){
                winner = player;
                continue;
            }

            winner = table.getWinnerByCompareCards(winner, player);
        }

        for (Integer seat : table.getInGamePlayers().keySet()) {
            PlayerInfo player = table.getInGamePlayers().get(seat);
            if (player.getRoleType() == RoleType.ROBOT){
                continue;
            }
            if (table.getPlayType() != PlayTypeEnum.changecard.getGameId()){
                continue;
            }
            //玩家牌型重置
            int[] cardOrgTmp = table.getPlayerCardsMap().get(player.getPlayerId());
            int[] cardsTmp = {cardOrgTmp[0],cardOrgTmp[1],cardOrgTmp[2]};
            player.setHandCards(cardsTmp);
        }

        if (winner.getRoleType() == RoleType.ROBOT){
            //机器人赢,不用操心了
            log.debug("AI机器人换牌策略启动,机器人赢,不用操心了winner = {},card = {}" ,winner.getPlayerId(),winner.getHandCards());
            //设置为执行策略机器人
            StoredObjManager.hset( RedisConst.ROBOT_POOL_STRATEGY_ID.getProfix()+table.getCurrGameOrderId(), RedisConst.ROBOT_POOL_STRATEGY_ID.getField(), winner.getPlayerId());
            return;
        }

        //机器人赢不了,我们就要换牌耍赖了
        int[] winnerCard = winner.getHandCards();
        int[] winnerFullCard = table.getPlayerCardsMap().get(winner.getPlayerId());
        int[] winnerMaxCard = getMaxCard(winner.getPlayerId(), table);
        log.debug("AI机器人换牌策略启动,玩家={},原始牌型card={},fullcard={}",winner.getPlayerId(),winnerCard,winnerFullCard);

        for (Integer seat : table.getInGamePlayers().keySet()) {
            PlayerInfo player = table.getInGamePlayers().get(seat);
            if (player == null) {
                continue;
            }

            //替换机器人牌
            if (robotId.equals(player.getPlayerId())){
                log.debug("AI机器人换牌策略启动,机器人={},原始牌型card={},fullcard={}",robotId,robotCard,robotFullCard);
                player.setHandCards(winnerMaxCard);
                table.getPlayerCardsMap().put(robotId, winnerFullCard);

                log.debug("AI机器人换牌策略启动,机器人={},换牌牌型card={},fullcard={}",robotId,player.getHandCards(),table.getPlayerCardsMap().get(robotId));
                log.debug("AI机器人换牌策略启动,玩家牌型={}",player.toSitDownString());

                //设置为执行策略机器人
                StoredObjManager.hset(
                        RedisConst.ROBOT_POOL_STRATEGY_ID.getProfix()+table.getCurrGameOrderId(),
                        RedisConst.ROBOT_POOL_STRATEGY_ID.getField(),
                        robotId);
                continue;
            }

            //替换赢家牌
            if (winner.getPlayerId().equals(player.getPlayerId())){
                player.setHandCards(robotCard);
                table.getPlayerCardsMap().put(player.getPlayerId(), robotFullCard);
                //换牌玩法
                if (table.getPlayType() == PlayTypeEnum.changecard.getGameId()){
                    int[] cardsTmp = {robotFullCard[0],robotFullCard[1],robotFullCard[2]};
                    player.setHandCards(cardsTmp);
                }

                log.debug("AI机器人换牌策略启动,玩家={},换牌牌型card={},fullcard={}",winner.getPlayerId(),player.getHandCards(),table.getPlayerCardsMap().get(player.getPlayerId()));
                log.debug("AI机器人换牌策略启动,玩家牌型={}",player.toSitDownString());
                continue;
            }
        }

    }

    /**
     * 获取玩家最大的手牌
     * @param playerId
     * @param table
     * @return
     */
    private int[] getMaxCard(String playerId , AbstractTable table){
        for (Integer seat : table.getInGamePlayers().keySet()) {
            PlayerInfo player = table.getInGamePlayers().get(seat);
            if (player == null) {
                continue;
            }

            if (!player.getPlayerId().equals(playerId)){
                continue;
            }

            if (table.getPlayType() != PlayTypeEnum.changecard.getGameId()){
                return player.getHandCards();
            }

            //当前玩家手牌
            int[] handcard = player.getHandCards();
            //换牌
            int[] changeCard = table.getChangeCard(playerId);

            //牌型A
            int[] tmpA = {changeCard[0],handcard[1],handcard[2]};
            PlayerInfo playerTmpA = player;
            playerTmpA.setHandCards(tmpA);
            //牌型B
            int[] tmpB = {handcard[0],changeCard[0],handcard[2]};
            PlayerInfo playerTmpB = player;
            playerTmpB.setHandCards(tmpB);
            //牌型C
            int[] tmpC = {handcard[0],handcard[1],changeCard[0]};
            PlayerInfo playerTmpC = player;
            playerTmpC.setHandCards(tmpC);

            PlayerInfo winner = table.getWinnerByCompareCards(player, playerTmpA);
            winner = table.getWinnerByCompareCards(winner, playerTmpB);
            winner = table.getWinnerByCompareCards(winner, playerTmpC);

            return winner.getHandCards();
        }

        return null;
    }

    /**
     * 资金池变化金额
     * @param pool
     * @return
     */
    private double poolChange(RobotPool pool){
        //资金池当前量
        String curPoolStr = StoredObjManager.get(RedisConst.ROBOT_POOL_CURRENT_MONEY.getProfix());
        double curPool = 0;
        if (!StringUtils.isEmpty(curPoolStr)){
            curPool = Double.parseDouble(curPoolStr);
        }

        return curPool + pool.getInitRobotPool();
    }

    /**
     * 总杀量池
     * @param pool
     * @return
     */
    private double totalKillPool(RobotPool pool){
        //杀量池
        String killPoolStr = StoredObjManager.get(RedisConst.ROBOT_POOL_KILL_POOL.getProfix());
        double curPool = 0;
        if (!StringUtils.isEmpty(killPoolStr)){
            curPool = Double.parseDouble(killPoolStr);
        }

        curPool = NumberUtils.double2Decimal(curPool * pool.getFlowRate() * 0.01);
        return curPool + pool.getInitKillPool();
    }

    /**
     * 机器人资金池X 操作
     * @param player
     * @param score
     * @param win
     */
    public void addRobotPool(PlayerInfo player ,double score, boolean win){
        if (player == null || player.getRoleType() != RoleType.ROBOT){
            return;
        }

        double incr = score;
        if (!win){
            incr = -score;
        }

        log.debug("AI机器人资金池变量 robotId = {}, score = {}", player.getPlayerId(), incr);
        StoredObjManager.incrByFloat(RedisConst.ROBOT_POOL_CURRENT_MONEY.getProfix(), incr);
    }

    /**
     * 总杀量池Z 操作
     * @param loseScore
     */
    public void addKillPool(double loseScore){
        StoredObjManager.incrByFloat(RedisConst.ROBOT_POOL_KILL_POOL.getProfix(), loseScore);
    }
}
